package com.baseframe.tool.utils.data;

import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 梳理树形结构的工具
 */
public class NodeUtil {


    /**
     * 获取节点数据 只能获取到子节点无法获取到子子孙孙节点
     * @param nodes 全部节点
     * @return 树形节点
     * @param <T> 泛型
     */
    @Deprecated
    public static<T extends Node<T> >  List<T> wrap(Collection<T> nodes){

        List<T> parentNodes = nodes.stream().filter(e->e.getParent()==null).collect(Collectors.toList());


        for (Node<T> parentNode : parentNodes) {

            List<T> childList = new ArrayList<>();
            for (T child : nodes) {
                if (Objects.equals(parentNode.getId(), child.getParent())){
                    childList.add(child);
                }
            }
            //2.给子节点排序
            childList = childList.stream().sorted(Comparator.comparing(Node::getSort)).collect(Collectors.toList());
            parentNode.setChildNode(childList);
        }

        //给父节点排序
        parentNodes = parentNodes.stream().sorted(Comparator.comparing(Node::getSort)).collect(Collectors.toList());

        return parentNodes;
    }

    @SuppressWarnings("all")
    private static<T extends Node<T>>  void wrapNode(Collection<T> nodes){


        for (T node : nodes) {
            List<T> childList = nodes
                    .stream()
                    .filter(e -> Objects.equals(e.getParent(), node.getId()))//获取当前节点的子节点
                    .sorted(Comparator.comparing(Node::getSort))
                    .collect(Collectors.toList()
                    );

            node.setChildNode(childList);

            wrapNode(childList);
        }

    }

    /**
     * 多级树的生成方法
     * @param nodes 节点
     * @return 树形节点
     * @param <T> 树形泛型
     */
    public static <T extends Node<T>> List<T> warpTree(Collection<T> nodes){

        wrapNode(nodes);
       return nodes.stream().filter(e->e.getParent()==null).sorted(Comparator.comparing(Node::getSort)).collect(Collectors.toList());
    }



    @Data
    public static class Node<T>{
        private Long id;
        private Long parent;
        private List<T> childNode;
        private Integer sort;
    }
}
